﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="KeyPhraseCloud.cs" company="Microsoft">
//   Microsoft
// </copyright>
// <summary>
//   Defines the KeyPhraseCloud type.
// </summary>
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.

// ATTENTION - THIS FILE CONTAINS THIRD PARTY OPEN SOURCE CODE: 3D Tag Cloud Widget for BlogEngine.NET
// IT IS CLEARED ONLY FOR LIMITED USE BY Doan Huynh FOR THE My Semantic Search PRODUCT.
// DO NOT USE OR SHARE THIS CODE WITHOUT APPROVAL PURSUANT TO THE MICROSOFT OPEN SOURCE SOFTWARE APPROVAL POLICY
// THE SOURCE CODE FOR 3D Tag Cloud Widget for BlogEngine.NET HAS BEEN MODIFIED
// --------------------------------------------------------------------------------------------------------------------

namespace MySemanticSearch.TagCloud
{
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;

    using Kit3D.Windows.Media.Media3D;

    using MySemanticSearch.Model;

    /// <summary>
    /// KeyPhrase in the tag cloud
    /// </summary>
    public class KeyPhraseCloud
    {
        /// <summary>
        /// Hyperlink color brush.
        /// </summary>
        private readonly Brush blueBrush = new SolidColorBrush(Colors.Blue);

        /// <summary>
        /// Label text color brush.
        /// </summary>
        private readonly Brush blackBrush = new SolidColorBrush(Colors.Black);

        /// <summary>
        /// Button background brush.
        /// </summary>
        private readonly Brush transparentBrush = new SolidColorBrush(Color.FromArgb(0, 0, 0, 240));

        /// <summary>
        /// Minimum score in the tag cloud.
        /// </summary>
        private readonly float minScore;

        /// <summary>
        /// Initializes a new instance of the <see cref="KeyPhraseCloud"/> class.
        /// </summary>
        /// <param name="coordinateX">
        /// The coordinate_x position.
        /// </param>
        /// <param name="coordinateY">
        /// The coordinateY position.
        /// </param>
        /// <param name="coordinateZ">
        /// The coordinateZ position.
        /// </param>
        /// <param name="text">
        /// The text displayed in the label.
        /// </param>
        /// <param name="score">
        /// The KeyPhrase score.
        /// </param>
        /// <param name="minScore">
        /// The min Score.
        /// </param>
        public KeyPhraseCloud(double coordinateX, double coordinateY, double coordinateZ, string text, float score, float minScore)
        {
            this.Score = score;
            this.minScore = minScore;
            this.MiddlePoint = new Point3D(coordinateX, coordinateY, coordinateZ);
            var block = new TextBlock { Text = text };

            this.KeyPhraseButton = new HyperlinkButton
                {
                    Content = block,
                    Foreground = this.blackBrush,
                    Background = this.transparentBrush,
                    BorderThickness = new Thickness(0),
                    Opacity = 0.1,
                    IsTabStop = false
                };

            ToolTipService.SetToolTip(this.KeyPhraseButton, "Score: " + this.Score);

            this.KeyPhraseButton.MouseEnter += this.KeyPhraseButtonMouseEnter;
            this.KeyPhraseButton.MouseLeave += this.KeyPhraseButtonMouseLeave;
            this.KeyPhraseButton.Click += this.InvokeKeyPhraseButtonClickEvent;
        }

        /// <summary>
        /// Handles click events
        /// </summary>
        public event RoutedEventHandler KeyPhraseButtonClickEvent;

        /// <summary>
        /// Gets or sets KeyPhraseButton.
        /// </summary>
        public HyperlinkButton KeyPhraseButton { get; set; }

        /// <summary>
        /// Gets or sets MiddlePoint.
        /// </summary>
        public Point3D MiddlePoint { get; set; }
        
        /// <summary>
        /// Gets or sets Score.
        /// </summary>
        public float Score { get; set; }

        /// <summary>
        /// Redraw the label.
        /// </summary>
        /// <param name="offsetX">
        /// The coordinate_x offset.
        /// </param>
        /// <param name="offsetY">
        /// The coordinateY offset.
        /// </param>
        public void Redraw(double offsetX, double offsetY)
        {
            var positionZ = this.MiddlePoint.Z + 200.0;
            this.KeyPhraseButton.FontSize = 4.0 * (positionZ / 100.0) * (1 + ((this.Score - this.minScore) * 3.0));
            var opacity = this.MiddlePoint.Z + 200.0;
            if (opacity > 255.0)
            {
                opacity = 255.0;
            }

            if (opacity < 0.0)
            {
                opacity = 0.0;
            }

            this.KeyPhraseButton.Opacity = opacity / 255.0;
            Canvas.SetLeft(this.KeyPhraseButton, this.MiddlePoint.X + offsetX - (this.KeyPhraseButton.ActualWidth / 2.0));
            Canvas.SetTop(this.KeyPhraseButton, -this.MiddlePoint.Y + offsetY - (this.KeyPhraseButton.ActualHeight / 2.0));
            Canvas.SetZIndex(this.KeyPhraseButton, Convert.ToInt32(this.MiddlePoint.Z));
        }

        /// <summary>
        /// This method attachs the tag propertie to the event and handles the event to
        /// the viewmodel
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The event arguments
        /// </param>
        private void InvokeKeyPhraseButtonClickEvent(object sender, RoutedEventArgs e)
        {
            var handler = this.KeyPhraseButtonClickEvent;
            if (handler == null || e == null)
            {
                return;
            }

            var tag = ((TextBlock)this.KeyPhraseButton.Content).Text;

            var eventargs = new SelectedTagEventArgs(tag);
            handler(this, eventargs);
        }
        
        /// <summary>
        /// Method for handling mouse leave events.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The eventargs.
        /// </param>
        private void KeyPhraseButtonMouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            ((HyperlinkButton)sender).Foreground = this.blackBrush;
        }

        /// <summary>
        /// Method for handling mouse enter events.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The eventargs.
        /// </param>
        private void KeyPhraseButtonMouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            ((HyperlinkButton)sender).Foreground = this.blueBrush;
        }
    }
}
